package com.zzj.ecology.framework.configuration.security.service;

import com.zzj.ecology.common.enums.LoginResultEnum;
import com.zzj.ecology.system.bean.system.SysRole;
import com.zzj.ecology.system.bean.system.SysUser;
import com.zzj.ecology.system.service.system.SysPermissionService;
import com.zzj.ecology.system.service.system.SysRoleService;
import com.zzj.ecology.system.service.system.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户认证
 */
@Component("userDetailsService")
public class CustomizeUserDetailsService implements UserDetailsService {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysPermissionService sysPermissionService;
    @Autowired
    private SysRoleService sysRoleService;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        // 用户名为空
        if (StringUtils.isEmpty(userName)) {
            //throw new InternalAuthenticationServiceException(LoginResultEnum.USER_ACCOUNT_NOT_EXIST.getName());
            //throw new LoginException(LoginResultEnum.USER_ACCOUNT_NOT_EXIST);
            throw new UsernameNotFoundException("用户登录 ID 不能为空");
        }
        SysUser sysUserDb = sysUserService.findByUsername(userName);
        //用户不存在
        if (sysUserDb == null) {
            //throw new InternalAuthenticationServiceException(LoginResultEnum.USER_ACCOUNT_NOT_EXIST.getName());
            //throw new LoginException(LoginResultEnum.USER_ACCOUNT_NOT_EXIST);
            throw new UsernameNotFoundException("用户登录 ID 不存在。");
        }
        //用户存在, 获取角色（权限）列表
        Integer id = sysUserDb.getUserId();

        //List<SysPermission> permissions = sysPermissionService.findListByUserId(id);
        List<SysRole> roles = sysRoleService.findRolesByUserId(id); // 查询到用户的所有角色权限

        /*
         * 定义一个集合用于保存org.springframework.security.core.GrantedAuthority接口或子实现类的
         * Collection<? extends GrantedAuthority> authorities集合
         *
         * Collection<? extends GrantedAuthority> authorities是用户的角色的集合
         * */
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();

        /*
         * 遍历用户的所有角色,增加到Collection<? extends GrantedAuthority> authorities集合中
         *
         * */
        for (SysRole sysRole : roles) {
            String roleCode = sysRole.getRoleCode();//获取权限英文代号
            if (!StringUtils.isEmpty(roleCode)) {
                authorities.add(new SimpleGrantedAuthority(roleCode));
            }
        }

        /*
         * 封装返回org.springframework.security.core.userdetails.User的UserDetails子对象
         * User(String username,String password,Collection<? extends GrantedAuthority> authorities)
         *
         * com.zeng.boot.web.configuration.CustomizingSpringSceurityConfiguration 中使用了加密技术,如下
         * auth.userDetailsService(customUserService).passwordEncoder(new BCryptPasswordEncoder());使用了加密
         *
         * 此处要对用户的密码进行加密,如何数据库已经加密了就不需要再加密
         *
         * */
//        User user = new User(sysUser.getUsername(), sysUser.getPassword(), authorities);
//        String password = new BCryptPasswordEncoder().encode(sysUserDb.getPassword());//对密码进行加密

        User userDetail = null;//封闭返回的UserDetails的子类
//        userDetail = new User(sysUserDb.getGlobalId(),sysUserDb.getPassword(),authorities);
        //userDetail = new User(sysUserDb.getUsername(),sysUserDb.getPassword(),authorities);

        userDetail = new User(sysUserDb.getUsername(),sysUserDb.getPassword(),
                sysUserDb.getEnabled(),
                sysUserDb.getNotExpired(),
                sysUserDb.getCredentialsNotExpired(),
                sysUserDb.getAccountNotLocked(),
                authorities);

        return userDetail;
    }

}
